<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/9/2
 * Time: 15:13
 */
namespace App\Services;

use App\Repositories\BankSupportRepository;
use App\Repositories\CollectMoneyBillRepository;
use App\Repositories\ThreeApiErrorLogsRepository;
use App\Repositories\UserBankCardRepository;
use App\Repositories\UserCreditCardRepository;
use App\Repositories\UserLevelPassageRepository;
use App\Repositories\UserPassageRepository;
use App\Repositories\UserRepository;
use App\Services\QuickPay\QuickPayFService;
use App\Services\QuickPay\QuickPayLService;
use Illuminate\Support\Facades\Log;

class CollectMoneyService extends CommonService
{
    protected $userRepository;
    protected $userPassageRepository;
    protected $userBankCardRepository;
    protected $userCreditCardRepository;
    protected $repaymentAccountWithdrawRepository;
    protected $userLevelPassageRepository;
    protected $collectMoneyBillRepository;
    protected $bankSupportRepository;
    protected $threeApiErrorLogsRepository;
    protected $collectMoneyProfitService;
    protected $messageService;
    protected $quickPayFService;
    protected $quickPayLService;

    public function __construct(UserRepository $userRepository,
                                UserPassageRepository $userPassageRepository,
                                UserBankCardRepository $userBankCardRepository,
                                UserCreditCardRepository $userCreditCardRepository,
                                UserLevelPassageRepository $userLevelPassageRepository,
                                CollectMoneyBillRepository $collectMoneyBillRepository,
                                BankSupportRepository $bankSupportRepository,
                                ThreeApiErrorLogsRepository $threeApiErrorLogsRepository,
                                CollectMoneyProfitService $collectMoneyProfitService,
                                MessageService $messageService,
                                QuickPayFService $quickPayFService,
                                QuickPayLService $quickPayLService)
    {
        $this->userRepository = $userRepository;
        $this->userPassageRepository = $userPassageRepository;
        $this->userBankCardRepository = $userBankCardRepository;
        $this->userCreditCardRepository = $userCreditCardRepository;
        $this->userLevelPassageRepository = $userLevelPassageRepository;
        $this->collectMoneyBillRepository = $collectMoneyBillRepository;
        $this->bankSupportRepository = $bankSupportRepository;
        $this->threeApiErrorLogsRepository = $threeApiErrorLogsRepository;
        $this->collectMoneyProfitService = $collectMoneyProfitService;
        $this->messageService = $messageService;
        $this->quickPayFService = $quickPayFService;
        $this->quickPayLService = $quickPayLService;
    }

    /**
     * 提现
     * {
    "transcode": "026",
    "merchno": "lmkj25se267f69f",
    "dsorderid": "AA21933882231973",
    "sign": "d3b344305e1d940639fc2175e768507a",
    "returncode": "0000",
    "errtext": "下单成功",
    "orderid": "2018102111522600100185629",
    "transtype": "23",
    "pay_info": "http:\/\/double.unspay.com\/unspay-creditCardRepayment-business\/quickPayWap\/prePay",
    "pay_code": "{\"accountId\":\"2120180620142221001\",\"amount\":\"10.00\",\"deductCardToken\":\"78A16E57D00E94F28F6AC1C992D32381\",\"delegatePayResponseUrl\":\"http:\/\/pay.huanqiuhuiju.com\/authsys\/weishua\/ysb\/df\/notify.do\",\"mac\":\"3EF176E3BF8F16519816A1F1D6456882\",\"memberId\":\"2018101913575200100138519\",\"merchantNo\":\"2110000000000000166321\",\"orderNo\":\"2018102111522600100185629\",\"pageResponseUrl\":\"https:\/\/dev.longmaoguanjia.com\/api\/notify\/landingc\/quick_money_return?orderNo=AA21933882231973\",\"purpose\":\"WS\",\"quickPayResponseUrl\":\"http:\/\/pay.huanqiuhuiju.com\/authsys\/weishua\/ysb\/pay\/notify.do\",\"repayCardToken\":\"F5572F639FE7F573D47CC6EC1B76485C\",\"repayCycle\":\"D0\"}"
    }
     *
     */
    public function withdraw($passageId, $user, $creditCardId, $bankCardId, $money, $expireDate, $cvn2)
    {
//        if (time() < strtotime('7:30') || time() > strtotime('22:30')) {
//            return $this->responseJson(10902);//交易时间:7:30-22:30
//        }
        //信用卡验证
        $userCreditCardRepository = $this->userCreditCardRepository->validateCreditCardIsUser($creditCardId, $user['user_id']);
        if (empty($userCreditCardRepository)) {
            return $this->responseJson(10306);//信用卡不存在
        }
        //储蓄卡验证
        $userBankCardRepository = $this->userBankCardRepository->validateBankCardIsUser($bankCardId, $user['user_id']);
        if (empty($userBankCardRepository)) {
            return $this->responseJson(10307);//储蓄卡不存在
        }
        //提现金额是否超出收银限额
        $bankSupport = $this->bankSupportRepository->byPassageIdAndBankCode($passageId, $userCreditCardRepository->bank_code);
        if (empty($bankSupport) || $bankSupport->is_support == 0) {
            return $this->responseJson(10901);//暂不支持该银行
        }
        //最低限额
        if ($money < $bankSupport->lowest_money) {
            $message = '最低限额' . $bankSupport->lowest_money . '元';
            return $this->responseJson(422, [], false, $message, $message);
        }
        //单笔限额
        if ($money > $bankSupport->every_time_money) {
            $message = '单笔限额' . $bankSupport->every_time_money . '元';
            return $this->responseJson(422, [], false, $message, $message);
        }
        //单日限额
        $collectMoneyEveryDayMoneyRedisKey = $this->collectMoneyEveryDayMoneyRedisKey() .
            'user_id_' . $user['user_id'] . '_credit_card_id_' . $creditCardId;
        $everyDayMoney = $this->redis()->get($collectMoneyEveryDayMoneyRedisKey);
        if ($everyDayMoney > $bankSupport->every_day_money) {
            $message = '单日限额' . $bankSupport->every_day_money . '元';
            return $this->responseJson(422, [], false, $message, $message);
        }
        if ($passageId == 2) {
            return $this->quickF($passageId, $money, $user, $userBankCardRepository, $userCreditCardRepository, $expireDate, $cvn2);
        }
        if ($passageId == 4) {
            return $this->quickL($passageId, $money, $user, $userBankCardRepository, $userCreditCardRepository, $expireDate, $cvn2);
        }
    }

    public function quickF($passageId, $money, $user, $userBankCardRepository, $userCreditCardRepository, $expireDate, $cvn2)
    {
        //用户费率
        $userFee = $this->userLevelPassageRepository->first($passageId, $user['level']);
        $orderNo = makeOrderNo();
        //是否已经拥有收银子商户号
        $isNo = $this->userPassageRepository->first($passageId, $user['user_id']);
        if (empty($isNo->sub_merchant_no)) {
            $result = $this->quickPayFService->subMerchantRegister($orderNo, $user['realname'], $user['idcard_number'], $userBankCardRepository->bank_code,
                $userBankCardRepository->bank_description, $userBankCardRepository->bank_no, $userBankCardRepository->bank_mobile);
            if ($result['response']['code'] == 0) {
                $subMerchantNo = $result['sub_mch_no'];
                $this->userPassageRepository->create([
                    'passage_id' => $passageId,
                    'user_id' => $user['user_id'],
                    'sub_merchant_no' => $subMerchantNo,
                ]);
            } else {
                return $this->responseJson(400, [], false, $result['response']['message'], $result['response']['message']);
            }
        } else {
            $subMerchantNo = $isNo->sub_merchant_no;
        }
        $orderNo = makeOrderNo();
        //修改卡号费率与收银金额
        $quickModifyFee = $this->quickPayFService->subMerchantFee($orderNo, $subMerchantNo, $user['realname'], $userBankCardRepository->bank_code,
            $userBankCardRepository->bank_description, $userBankCardRepository->bank_no, $userBankCardRepository->bank_mobile, $userFee->rate, $userFee->second_rate);
        Log::info('收银接口修改卡号费率返回数据' . json_encode($quickModifyFee));
        if ($quickModifyFee['response']['code'] != 0) {
            return $this->responseJson(422, [], false, $quickModifyFee['response']['message'], $quickModifyFee['response']['message']);//您的信息有误
        }
        $orderNo = makeOrderNo();
        $quickPay = $this->quickPayFService->trade($orderNo, $subMerchantNo, $user['realname'], $userCreditCardRepository->bank_no,
            $userCreditCardRepository->bank_mobile, $expireDate, $cvn2,
            $money, $userFee->rate, $userFee->second_rate);
        Log::info('收银接口返回数据' . json_encode($quickPay));
        if ($quickPay['response']['code'] != 0) {
            return $this->responseJson(422, [], false, $quickPay['response']['message'], $quickPay['response']['message']);
        }
        $returnUrl = $quickPay['response']['data']['pay_return_url'];
        if ($quickPay['response']['data']['request'] == 'POST') {
            $data = [
                'pay_success_return_url' => $returnUrl,
                'pay_url' => $quickPay['response']['data']['pay_url'],
                'request_format' => 'yes_form_data'
            ];
        } else {
            $data = [
                'pay_success_return_url' => $returnUrl,
                'pay_url' => $quickPay['response']['data']['pay_url'],
                'request_format' => 'no_form_data'
            ];
        }
        //收银明细
        $serviceCharge = round($money * $userFee->rate + $userFee->second_rate, 2);
        $transferredMoney = $money - $serviceCharge;
        $info = [
            'bill_sn' => $orderNo,
            'user_id' => $user['user_id'],
            'passage_id' => $passageId,
            'credit_card_id' => $userCreditCardRepository->id,
            'bank_card_id' => $userBankCardRepository->id,
            'collect_money' => $money,
            'transferred_money' => $transferredMoney,
            'collect_service_charge' => $serviceCharge,
            'collect_money_status' => 6000,
            'create_month' => date('Y-m'),
            'create_collect_time' => time(),
        ];
        $id = $this->collectMoneyBillRepository->insertGetId($info);
        return $this->responseJson(0, $data);
    }

    public function quickL($passageId, $money, $user, $userBankCardRepository, $userCreditCardRepository, $expireDate, $cvn2)
    {
        //用户费率
        $userFee = $this->userLevelPassageRepository->first($passageId, $user['level']);
        $orderNo = makeOrderNo();
        //是否已经拥有收银子商户号
        $isNo = $this->userPassageRepository->first($passageId, $user['user_id']);
        if (empty($isNo->sub_merchant_no)) {
            $result = $this->quickPayLService->subMerchantRegister($orderNo, $user['realname'], $user['idcard_number'], $userBankCardRepository->bank_code,
                $userBankCardRepository->bank_description, $userBankCardRepository->bank_no, $userBankCardRepository->bank_mobile);
            if ($result['response']['code'] == 0) {
                $subMerchantNo = $result['sub_mch_no'];
                $this->userPassageRepository->create([
                    'passage_id' => $passageId,
                    'user_id' => $user['user_id'],
                    'sub_merchant_no' => $subMerchantNo,
                ]);
            } else {
                return $this->responseJson(400, [], false, $result['response']['message'], $result['response']['message']);
            }
        } else {
            $subMerchantNo = $isNo->sub_merchant_no;
        }
        $orderNo = makeOrderNo();
        //修改卡号费率与收银金额
        $quickModifyFee = $this->quickPayLService->subMerchantFee($orderNo, $subMerchantNo, $user['realname'], $userBankCardRepository->bank_code,
            $userBankCardRepository->bank_description, $userBankCardRepository->bank_no, $userBankCardRepository->bank_mobile, $userFee->rate, $userFee->second_rate);
        Log::info('收银接口修改卡号费率返回数据' . json_encode($quickModifyFee));
        if ($quickModifyFee['response']['code'] != 0) {
            return $this->responseJson(422, [], false, $quickModifyFee['response']['message'], $quickModifyFee['response']['message']);//您的信息有误
        }
        $orderNo = makeOrderNo();
        $quickPay = $this->quickPayLService->trade($orderNo, $subMerchantNo, $user['realname'], $userCreditCardRepository->bank_code, $userCreditCardRepository->bank_no,
            $userCreditCardRepository->bank_mobile, $expireDate, $cvn2,
            $money, $userFee->rate, $userFee->second_rate);
        Log::info('收银接口返回数据' . json_encode($quickPay));
        if ($quickPay['response']['code'] != 0) {
            return $this->responseJson(422, [], false, $quickPay['response']['message'], $quickPay['response']['message']);
        }
        $returnUrl = $quickPay['response']['data']['pay_return_url'];
        if ($quickPay['response']['data']['request'] == 'POST') {
            $data = [
                'pay_success_return_url' => $returnUrl,
                'pay_url' => $quickPay['response']['data']['pay_url'],
                'request_format' => 'yes_form_data'
            ];
        } else {
            $data = [
                'pay_success_return_url' => $returnUrl,
                'pay_url' => $quickPay['response']['data']['pay_url'],
                'request_format' => 'no_form_data'
            ];
        }
        //收银明细
        $serviceCharge = round($money * $userFee->rate + $userFee->second_rate, 2);
        $transferredMoney = $money - $serviceCharge;
        $info = [
            'bill_sn' => $orderNo,
            'user_id' => $user['user_id'],
            'passage_id' => $passageId,
            'credit_card_id' => $userCreditCardRepository->id,
            'bank_card_id' => $userBankCardRepository->id,
            'collect_money' => $money,
            'transferred_money' => $transferredMoney,
            'collect_service_charge' => $serviceCharge,
            'collect_money_status' => 6000,
            'create_month' => date('Y-m'),
            'create_collect_time' => time(),
        ];
        $id = $this->collectMoneyBillRepository->insertGetId($info);
        return $this->responseJson(0, $data);
    }

    /**
     * 交易查询是否到账任务
     * 00 成功 02 失败 04订单关闭 01 处理中 半个小时后再次发起对账。 99 订单号不存在
     * array:7 [
     * "transcode" => "902"
     * "merchno" => "lmkj25se267f69f"
     * "dsorderid" => "A904652975751551"
     * "sign" => "5ebf820a840cb272fedd1170672015a1"
     * "returncode" => "0000"
     * "errtext" => "成功"
     * "status" => "99"
     * ]
     * array:14 [
     * "transcode" => "902"
     * "merchno" => "lmkj25se267f69f"
     * "dsorderid" => "A904456629703671"
     * "sign" => "6bc4fa26053917187f393cb6d8eaeaf9"
     * "returncode" => "0000"
     * "errtext" => "成功"
     * "orderid" => "2018090415173500100120279"
     * "amount" => "10.00"
     * "status" => "00"
     * "transtype" => "20"
     * "currency" => "CNY"
     * "paytime" => "20180904153636"
     * "signType" => "MD5"
     * "message" => "成功"
     * ]
     */
    public function tradeQueryJobs()
    {
        Log::alert('collect_money_tradeQueryJobs');
        $collectMoneyWithdrawQueryRedisKey = $this->collectMoneyWithdrawQueryRedisKey();
        $getTrade = $this->redis()->lRange($collectMoneyWithdrawQueryRedisKey, 0, -1);
        if (!empty($getTrade)) {
            foreach ($getTrade as $key=>$value) {
                //第三方接口单次访问需2s，防止并发，1分钟对账10条
                if ($key < 10) {
                    $info = json_decode($value, true);
                    $result = $this->landingCollectMoneyCService->receiveAndPaymentSelect($info['bill_sn'], $info['transtype']);
                    Log::alert('collect_money_tradeQueryJobs_result==' . json_encode($result));
                    //成功
                    if ($result['status'] == '00') {
                        $this->redis()->lRem($collectMoneyWithdrawQueryRedisKey, 0, $value);
                        //如果还没收到成功的回调
                        //收银收益分配
                        $this->collectMoneyProfitService->collectMoneyProfit($result['dsorderid']);
                    }
                    //失败或订单号不存在
                    if ($result['status'] == '02' || $result['status'] == '99') {
                        $failMessage = isset($result['message']) ? $result['message'] : '';
                        $this->collectMoneyBillRepository->updateBillStatus($result['dsorderid'], 6003, $failMessage);//失败
                        $this->redis()->lRem($collectMoneyWithdrawQueryRedisKey, 0, $value);
                        //发送收银失败消息提醒
                        $user = $this->userRepository->byId($info['user_id']);
                        $creditCard = $this->userCreditCardRepository->byId($info['credit_card_id']);
                        $this->messageService->messageTemplate(4, $user->invited_code, $creditCard->bank_no, $creditCard->bank_description,
                            $info['collect_money'], '', '', $info['id'], '', '');
                    }
                    //订单超时关闭
                    if ($result['status'] == '04') {
                        $this->collectMoneyBillRepository->updateBillStatus($result['dsorderid'], 6004, '订单超时关闭');//订单超时关闭
                        $this->redis()->lRem($collectMoneyWithdrawQueryRedisKey, 0, $value);
                    }
                }
            }
        }
    }

    /**
     * 交易记录
     * @param $userId
     * @param $creditCardId
     * @return \Illuminate\Http\JsonResponse
     */
    public function tradeRecord($userId, $creditCardId)
    {
        $detail = $this->collectMoneyBillRepository->groupByMonth($userId, $creditCardId, 6002);
        $data = [];
        foreach ($detail as $key=>$value) {
            $data[$key] = $value;
            $data[$key]['detail'] = $this->collectMoneyBillRepository->getTradeRecord($value['create_month'], $userId, $creditCardId);
        }
        return $this->responseJson(0, $data);
    }

    /**
     * 交易明细
     * @param $userId
     * @param $collectMoneyStatus
     * @return \Illuminate\Http\JsonResponse
     */
    public function getDetail($userId, $collectMoneyStatus, $page)
    {
        $data = $this->collectMoneyBillRepository->getDetail($userId, $collectMoneyStatus, $page, 10);
        $result = [];
        if (!empty($data)) {
            foreach ($data as $key=>$value) {
                $creditCard = $this->userBankCardRepository->byId($value['bank_card_id']);
                $result[$key] = $value;
                $result[$key]['bank_no'] = $creditCard->bank_no;
                $result[$key]['bank_description'] = $creditCard->bank_description;
            }
        }
        return $this->responseJson(0, $result);
    }
}